<!--
 * @Descripttion: 
 * @Author: Kevin
 * @Date: 2022-06-15 13:45:02
 * @LastEditors: Tommy Chen
 * @LastEditTime: 2024-08-28
-->
<template>
  <RjModal
    width="624px"
    :visible="isVisible"
    :title="modalTitle"
    :confirmLoading="confirmLoading"
    @ok="onOk"
    @cancel="onCancel"
  >
    <a-form-model
      :model="policyForm"
      :labelCol="{ span: 10 }"
      :wrapperCol="{ span: 14 }"
      labelAlign="left"
      :rules="rules"
      :colon="false"
      ref="policyFormRef"
    >
      <a-form-model-item :label="$t('authPolicy.name')" prop="name">
        <a-input
          v-model="policyForm.name"
          :placeholder="$t('common.inuptTip')"
        />
      </a-form-model-item>

      <a-form-model-item prop="noOfDevice">
        <a-space slot="label" :size="4">
          {{ $t('userManage.printConcurrentDevices') }}
          <a-tooltip>
            <template slot="title">
              {{ $t('authPolicy.qualityTip') }}
            </template>
            <icon-font type="ic-help" />
          </a-tooltip>
        </a-space>
        <a-space v-if="policyForm.noOfDevice == 'customDeviceNo'">
          <a-select v-model="policyForm.noOfDevice" :options="deviceOptions" />
          <a-input-number
            style="width: 241px"
            @change="validateField('noOfDevice')"
            v-model="customDeviceNo"
          />
        </a-space>
        <a-select
          v-else
          v-model="policyForm.noOfDevice"
          :options="deviceOptions"
        />
      </a-form-model-item>

      <a-form-model-item prop="timePeriod">
        <a-space slot="label" :size="4">
          {{ $t('userManage.validatePeriod') }}
          <a-tooltip>
            <template slot="title">
              <div>{{ $t('authPolicy.periodTip1') }}</div>
              <div>{{ $t('authPolicy.periodTip2') }}</div>
            </template>
            <icon-font type="ic-help" />
          </a-tooltip>
        </a-space>
        <a-space v-if="policyForm.timePeriod == 'userdefinedperiod'">
          <a-select
            @change="validateField('timePeriod')"
            v-model="policyForm.timePeriod"
            :options="periodOptions"
          >
          </a-select>
          <a-input
            :maxLength="6"
            @input="(e) => validateField('timePeriod', e)"
            v-model="customTimePeriod.value"
          />
          <a-select
            @change="changeRules('timePeriod')"
            v-model="customTimePeriod.unit"
            :options="timePeriodUnitOptions"
            class="w-125"
          />
        </a-space>
        <a-select
          v-else
          v-model="policyForm.timePeriod"
          :options="periodOptions"
        />
      </a-form-model-item>

      <a-form-model-item prop="quota">
        <a-space slot="label" :size="4">
          {{ $t('userManage.printDataQuota') }}
          <a-tooltip>
            <template slot="title">
              <div>{{ $t('authPolicy.quotaTip1') }}</div>
              <div>{{ $t('authPolicy.quotaTip2') }}</div>
            </template>
            <icon-font type="ic-help" />
          </a-tooltip>
        </a-space>
        <a-space v-if="policyForm.quota == 'userdefined'">
          <a-select
            @change="validateField('quota')"
            v-model="policyForm.quota"
            :options="dataQuotaOptions"
          />
          <a-input
            :maxLength="5"
            @input="(e) => validateField('quota', e)"
            v-model="customQuota.value"
          />
          <a-select
            @change="changeRules('quota')"
            v-model="customQuota.unit"
            :options="quotaUnitOptions"
            class="w-125"
          />
        </a-space>
        <a-select
          v-else
          v-model="policyForm.quota"
          :options="dataQuotaOptions"
        />
      </a-form-model-item>

      <a-form-model-item
        :label="$t('userManage.profileModalBindMACFirstUse')"
        class="flex col-top"
      >
        <a-switch v-model="policyForm.bindMac" />
      </a-form-model-item>

      <a-form-model-item>
        <a-space slot="label" :size="4">
          {{ $t('authPolicy.radiusDynamic') }}
          <a-tooltip>
            <template slot="title">
              <div>{{ $t('authPolicy.radiusTip1') }}</div>
              <div>{{ $t('authPolicy.radiusTip2') }}</div>
            </template>
            <icon-font type="ic-help" />
          </a-tooltip>
        </a-space>
        <a-checkbox-group v-model="authParamTypes">
          <a-checkbox
            v-for="(authOpt, index) in authOptions"
            :key="index"
            :value="authOpt.value"
          >
            <!-- 自定义label -->
            <span class="custom-label">{{ authOpt.label }}</span>
            <span class="dot1x-label ml-8" v-if="authOpt.value === 'vlan'">
              802.1X
            </span>
          </a-checkbox>
        </a-checkbox-group>
      </a-form-model-item>

      <div v-show="authParamTypes.includes('qos')">
        <div class="item-title">QoS</div>
        <a-form-model-item
          :label="$t('userManage.printDownloadSpeed')"
          prop="downloadRateLimit"
          :class="{
            flex: policyForm.downloadRateLimit !== 'userdefinedDownload',
          }"
        >
          <a-space v-if="policyForm.downloadRateLimit == 'userdefinedDownload'">
            <a-select
              @change="validateField('downloadRateLimit')"
              v-model="policyForm.downloadRateLimit"
              :options="downloadSpeedOptions"
            />
            <a-input
              :maxLength="8"
              @input="(e) => validateField('downloadRateLimit', e)"
              v-model="customDownloadRateLimit.value"
            />
            <a-select
              @change="changeRules('downloadRateLimit')"
              v-model="customDownloadRateLimit.unit"
              :options="downloadRateUnitOptions"
              class="w-125"
            />
          </a-space>
          <a-select
            v-else
            v-model="policyForm.downloadRateLimit"
            :options="downloadSpeedOptions"
          />
        </a-form-model-item>
        <a-form-model-item
          :label="$t('userManage.printUploadSpeed')"
          prop="uploadRateLimit"
          :class="{ flex: policyForm.uploadRateLimit !== 'userdefinedUpload' }"
        >
          <a-space v-if="policyForm.uploadRateLimit == 'userdefinedUpload'">
            <a-select
              @change="validateField('uploadRateLimit')"
              v-model="policyForm.uploadRateLimit"
              :options="uploadSpeedOptions"
            />
            <a-input
              :maxLength="8"
              @input="(e) => validateField('uploadRateLimit', e)"
              v-model="customUploadRateLimit.value"
            />
            <a-select
              @change="changeRules('uploadRateLimit')"
              v-model="customUploadRateLimit.unit"
              :options="uploadRateUnitOptions"
              class="w-125"
            />
          </a-space>
          <a-select
            v-else
            v-model="policyForm.uploadRateLimit"
            :options="uploadSpeedOptions"
          />
        </a-form-model-item>
      </div>

      <div v-show="authParamTypes.includes('vlan')">
        <div class="item-title">
          VLAN
          <span class="dot1x-label"> 802.1X </span>
        </div>
        <a-form-model-item class="required-item" label="VLAN" prop="vlanId">
          <a-input
            v-model="policyForm.vlanId"
            :placeholder="$t('authPolicy.vlan')"
          />
        </a-form-model-item>
      </div>
    </a-form-model>
  </RjModal>
</template>

<script>
import { requestHttp, maccApi, ValiDateTools } from '@utils/index';
import { mapState } from 'vuex';
import authSysMixin from '@project/authSys/mixin/authSysMixin';
import i18n from '@/locales';
import {
  downloadSpeedOptions,
  uploadSpeedOptions,
  periodOptions,
  dataQuotaOptions,
  quotaUnites,
  timePeriodUnits,
  uploadRateUnits,
  downloadRateUnits,
} from './options';
import { getByteLength } from '@/utils';
export default {
  name: 'addAuthSysModal',
  mixins: [authSysMixin],
  data() {
    let deviceOptions = [];
    for (let i = 0; i < 10; i++) {
      if (!i) {
        deviceOptions.push({ label: 'Unlimited', value: i });
      } else {
        deviceOptions.push({ label: i, value: i });
      }
    }
    deviceOptions.push({
      label: i18n.t('userManage.custom'),
      value: 'customDeviceNo',
    });
    const checkDeviceNo = (rule, val, cb) => {
      if (val == 'customDeviceNo') {
        let min, max;
        min = 1;
        max = 500;
        if (
          Number(this.customDeviceNo) < min ||
          Number(this.customDeviceNo) > max
        ) {
          cb(
            new Error(
              this.$t('userManage.profileModalTimePeriodTip', {
                min,
                max,
              })
            )
          );
        } else {
          cb();
        }
      } else {
        cb();
      }
    };
    const checkTimePeriod = (rule, val, cb) => {
      if (val == 'userdefinedperiod') {
        let min, max;
        switch (this.customTimePeriod.unit) {
          case 'minutes':
            min = 1;
            max = 10 ** 5;
            break;
          case 'hours':
            min = 1;
            max = 8760;
            break;
          case 'days':
            min = 1;
            max = 365;
            break;
          case 'weeks':
            min = 1;
            max = 52;
            break;
          default:
            break;
        }
        if (
          Number(this.customTimePeriod.value) < min ||
          Number(this.customTimePeriod.value) > max
        ) {
          cb(
            new Error(
              this.$t('userManage.profileModalTimePeriodTip', {
                min: min.toLocaleString('en-US'),
                max: max.toLocaleString('en-US'),
              })
            )
          );
        } else {
          cb();
        }
      } else {
        cb();
      }
    };
    const checkQuota = (rule, val, cb) => {
      let min, max;
      if (this.customQuota.unit == 'MB') {
        min = 1;
        max = 10 ** 4;
      } else {
        min = 1;
        max = 10 ** 2;
      }
      if (val == 'userdefined') {
        if (
          Number(this.customQuota.value) < min ||
          Number(this.customQuota.value) > max
        ) {
          cb(
            new Error(
              this.$t('userManage.profileModalTimePeriodTip', {
                min: min.toLocaleString('en-US'),
                max: max.toLocaleString('en-US'),
              })
            )
          );
        } else {
          cb();
        }
      } else {
        cb();
      }
    };
    const checkUploadRateLimit = (rule, val, cb) => {
      let min, max;
      if (this.customUploadRateLimit.unit == 'Kbps') {
        min = 1;
        max = 10 ** 7;
      } else {
        min = 1;
        max = 10 ** 4;
      }
      if (val == 'userdefinedUpload') {
        if (
          Number(this.customUploadRateLimit.value) < min ||
          Number(this.customUploadRateLimit.value) > max
        ) {
          cb(
            new Error(
              this.$t('userManage.profileModalTimePeriodTip', {
                min: min.toLocaleString('en-US'),
                max: max.toLocaleString('en-US'),
              })
            )
          );
        } else {
          cb();
        }
      } else {
        cb();
      }
    };
    const checkDownloadRateLimit = (rule, val, cb) => {
      let min, max;
      if (this.customDownloadRateLimit.unit == 'Kbps') {
        min = 1;
        max = 10 ** 7;
      } else {
        min = 1;
        max = 10 ** 4;
      }
      if (val == 'userdefinedDownload') {
        if (
          Number(this.customDownloadRateLimit.value) < min ||
          Number(this.customDownloadRateLimit.value) > max
        ) {
          cb(
            new Error(
              this.$t('userManage.profileModalTimePeriodTip', {
                min: min.toLocaleString('en-US'),
                max: max.toLocaleString('en-US'),
              })
            )
          );
        } else {
          cb();
        }
      } else {
        cb();
      }
    };

    let validateVlan = (rules, value, callback) => {
      if (!this.authParamTypes.includes('vlan')) {
        return callback();
      }

      if (!value) {
        callback(new Error(this.$t('common.mustEnter')));
      } else if (!ValiDateTools.checkRangeNum(value, 1, 4094)) {
        callback(new Error(this.$t('common.rangeCustom', [1, 4094])));
      } else {
        callback();
      }
    };

    const rules = {
      name: [
        {
          message: this.$t('common.byteRange', [64]),
          max: 64,
          trigger: 'blur',
        },
        {
          required: true,
          message: this.$t('common.mustEnter'),
          trigger: 'blur',
        },
      ],
      noOfDevice: [
        {
          validator: checkDeviceNo,
        },
      ],
      timePeriod: [
        {
          validator: checkTimePeriod,
        },
      ],
      quota: [
        {
          validator: (rule, val, cb) => checkQuota(rule, val, cb),
        },
      ],
      uploadRateLimit: [
        {
          validator: checkUploadRateLimit,
        },
      ],
      downloadRateLimit: [
        {
          validator: checkDownloadRateLimit,
        },
      ],
      vlanId: [{ validator: validateVlan, trigger: 'blur' }],
    };
    return {
      authParamTypes: [],
      authOptions: [
        { label: 'QoS', value: 'qos' },
        { label: 'VLAN', value: 'vlan' },
        // { label: 'Orange', value: 'Orange' },
      ],
      isVisible: false,
      policyForm: {
        noOfDevice: '3',
        timePeriod: 0,
        quota: 0,
        uploadRateLimit: 0,
        downloadRateLimit: 0,
        vlanId: null,
      },
      rules,
      deviceOptions,
      dataQuotaOptions,
      periodOptions,
      uploadSpeedOptions,
      downloadSpeedOptions,
      customDeviceNo: '',
      customQuota: {
        value: '',
        unit: 'MB',
      },
      customTimePeriod: {
        value: '',
        unit: 'minutes',
      },
      customUploadRateLimit: {
        value: '',
        unit: 'Kbps',
      },
      customDownloadRateLimit: {
        value: '',
        unit: 'Kbps',
      },
      confirmLoading: false,
      timePeriodUnitOptions: timePeriodUnits,
      quotaUnitOptions: quotaUnites,
      uploadRateUnitOptions: uploadRateUnits,
      downloadRateUnitOptions: downloadRateUnits,
    };
  },
  computed: {
    modalTitle() {
      return this.policyForm.uuid
        ? this.$t('authPolicy.edit')
        : this.$t('localAccount.addAuthPlicy2');
    },
  },
  mounted() {},
  methods: {
    openModal(data) {
      this.isVisible = true;
      if (data) {
        this.policyForm = data;
        //  bindMac和isBindSsid都是数字类型的，传1、0
        this.policyForm.bindMac = Boolean(data.bindMac); // tommy 240719 这里先关闭后续再打开
        this.policyForm.isBindSsid = 0;
        if (this.policyForm.vlanId) {
          this.authParamTypes.push('vlan');
        }
        if (
          this.policyForm.downloadRateLimit ||
          this.policyForm.downloadRateLimit === 0
        ) {
          this.authParamTypes.push('qos');
        }
      }
    },
    onOk() {
      this.$refs.policyFormRef.validate((valid) => {
        if (valid) {
          let params = { ...this.policyForm };
          params.packageType = 'COMMON';
          params.groupId = this.groupId;
          params.bindMac = params.bindMac ? 1 : 0;

          // 自定义设备数量
          if (this.policyForm.noOfDevice == 'customDeviceNo') {
            params.noOfDevice = this.customDeviceNo;
          }
          // 自定义downloadRateLimit处理
          if (this.policyForm.downloadRateLimit == 'userdefinedDownload') {
            params.downloadRateLimit =
              this.customDownloadRateLimit.unit !== 'Kbps'
                ? this.customDownloadRateLimit.value * 1024
                : this.customDownloadRateLimit.value;
          }
          // 自定义UploadRateLimit处理
          if (this.policyForm.uploadRateLimit == 'userdefinedUpload') {
            params.uploadRateLimit =
              this.customUploadRateLimit.unit !== 'Kbps'
                ? this.customUploadRateLimit.value * 1024
                : this.customUploadRateLimit.value;
          }
          // 自定义timePeriod处理
          if (this.policyForm.timePeriod == 'userdefinedperiod') {
            if (this.customTimePeriod.unit == 'hours') {
              params.timePeriod = this.customTimePeriod.value * 60;
            } else if (this.customTimePeriod.unit == 'days') {
              params.timePeriod = this.customTimePeriod.value * 60 * 24;
            } else if (this.customTimePeriod.unit == 'weeks') {
              params.timePeriod = this.customTimePeriod.value * 60 * 24 * 7;
            } else {
              params.timePeriod = this.customTimePeriod.value;
            }
          }
          // 自定义quota处理
          if (this.policyForm.quota == 'userdefined') {
            params.quota =
              this.customQuota.unit !== 'MB'
                ? this.customQuota.value * 1024
                : this.customQuota.value;
          }

          if (!this.authParamTypes.includes('qos')) {
            delete params.downloadRateLimit;
            delete params.uploadRateLimit;
          }

          if (!this.authParamTypes.includes('vlan')) {
            delete params.vlanId;
          }

          if (this.policyForm.uuid) {
            this.editAuthPolicy(params);
          } else {
            this.addAuthPolicy(params);
          }
        }
      });
    },
    validateField(field, e) {
      if (e) {
        let map = {
          noOfDevice: 'customDeviceNo',
          timePeriod: 'customTimePeriod',
          quota: 'customQuota',
          uploadRateLimit: 'customUploadRateLimit',
          downloadRateLimit: 'customDownloadRateLimit',
        };
        let value = e.target.value;
        this[map[field]].value = value.replace(/\D/g, '');
      }
      this.$refs.policyFormRef.validateField(field);
    },
    changeRules(field) {
      this.$refs.policyFormRef.validateField(field);
    },
    async editAuthPolicy(params) {
      let querys = {
        tenantId: this.tenantInfo.tenantId,
        group_id: this.groupId,
      };
      let replaces = {
        tenantName: encodeURI(this.tenantInfo.tenantName),
        userName: encodeURI(this.userInfo.account),
        groupId: this.groupId,
      };
      // 修改
      this.confirmLoading = true;
      let res = await this.requestHttpAuth({
        api: maccApi.MACC_PROFILE_UPDATE_POST_API,
        method: 'POST',
        querys,
        replaces,
        params,
      });
      this.confirmLoading = false;
      if (res.data.code === 0) {
        this.$message.success(this.$t('common.editSuccess'));
        this.$emit('refreshList');
        this.onCancel();
      } else {
        this.$message.warning(res.data.msg);
      }
    },
    async addAuthPolicy(params) {
      let querys = {
        tenantId: this.tenantInfo.tenantId,
        ishttps: false,
      };
      let replaces = {
        tenantName: encodeURI(this.tenantInfo.tenantName),
        userName: encodeURI(this.userInfo.account),
        groupId: this.groupId,
      };
      this.confirmLoading = true;
      let res = await this.requestHttpAuth({
        api: maccApi.MACC_PROFILE_ADD_POST_API,
        method: 'POST',
        querys,
        replaces,
        params,
      });
      this.confirmLoading = false;
      if (res.data.code === 0) {
        this.$message.success(this.$t('common.addSuceess'));
        this.$emit('refreshList', res.data.data.profileId);
        this.onCancel();
      } else {
        this.$message.warning(res.data.msg);
      }
    },
    onCancel() {
      this.isVisible = false;
      this.resetForm();
    },
    resetForm() {
      this.authParamTypes = [];
      this.policyForm = {
        noOfDevice: '3',
        timePeriod: 0,
        quota: 0,
        uploadRateLimit: 0,
        downloadRateLimit: 0,
      };
      this.customTimePeriod = {
        value: '',
        unit: 'minutes',
      };
      this.customUploadRateLimit = {
        value: '',
        unit: 'Kbps',
      };
      this.customDownloadRateLimit = {
        value: '',
        unit: 'Kbps',
      };
      this.customQuota = {
        value: '',
        unit: 'MB',
      };
    },
  },
};
</script>

<style lang="less" scoped>
@import url('@/project/authSys/assets/skin/common.less');
.item-title {
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 16px;
  font-weight: 600;
  color: @text-title;
  margin-bottom: 16px;
  margin-top: 24px;
  &::before {
    content: '';
    height: 14px;
    width: 3px;
    background: @theme-color;
    display: inline-block;
  }
}
.flex {
  display: flex !important;
  flex-direction: row !important;
  align-items: center;
}
.col-top {
  align-items: flex-start !important;
}
.w-334 {
  width: 334px;
}
.w-240 {
  width: 240px;
}
.ml-8 {
  margin-left: 8px;
}
.dot1x-label {
  border: 1px solid @theme-focus;
  background: @theme-light;
  color: @theme-color;
  font-size: 12px;
  height: 20px;
  width: 54px;
  border-radius: 2px;
  text-align: center;
  display: inline-block;
}
</style>
